﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;

namespace RiskMan.DataClass.Models.Plaza_II.FortsFutInfoRepl
{
    /// <summary>
    /// Таблица 37. Поля таблицы fut_sess_contents - Cправочник торгуемых инструментов
    /// Таблица содержит справочник инструментов, назначенных к торгам в сессию.
    /// Состояние сессии имеет приоритет над состоянием инструмента. То есть, если сессия находится в
    /// состоянии «приостановлена» или «завершена», то по всем инструмента нельзя торговать, независимо от
    /// значения state в инструменте.
    /// </summary>
    public class FutSessContents : INotifyPropertyChanged
    {
        #region private

        private long _replId;
        private long _replRev;
        private long _replAct;
        private int _sessId;
        private int _isinId;

        private string _shortIsin;
        private string _isin;
        private string _name;
        private int _instTerm;
        private string _codeVcb;
        private int _isLimited;
        private Decimal _limitUp;
        private Decimal _limitDown;
        private Decimal _oldKotir;
        private Decimal _buyDeposit;
        private Decimal _sellDeposit;
        private int _roundto;
        private Decimal _minStep;
        private int _lotVolume;
        private Decimal _stepPrice;
        private DateTime _dPg;
        private int _isSpread;
        private Decimal _coeff;
        private DateTime _dExp;
        private int _isPercent;
        private Decimal _percentRate;
        private Decimal _lastClQuote;
        private int _signs;
        private int _isTradeEvening;
        private int _ticker;
        private int _state;
        private int _priceDir;
        private int _multilegType;
        private int _legsQty;
        private Decimal _stepPriceClr;
        private Decimal _stepPriceInterclr;
        private Decimal _stepPriceCurr;
        private DateTime _dStart;
        private Decimal _exchPay;

        #endregion

        #region public

        /// <summary>
        /// Служебное поле подсистемы репликации
        /// </summary>
        public long ReplId
        {
            get { return _replId; }
            set
            {
                if (_replId != value)
                {
                    _replId = value;
                    RaisePropertyChanged("ReplId");
                }
            }
        }

        /// <summary>
        /// Служебное поле подсистемы репликации
        /// </summary>
        public long ReplRev
        {
            get { return _replRev; }
            set
            {
                if (_replRev != value)
                {
                    _replRev = value;
                    RaisePropertyChanged("ReplRev");
                }
            }
        }

        /// <summary>
        /// Служебное поле подсистемы репликации
        /// </summary>
        public long ReplAct
        {
            get { return _replAct; }
            set
            {
                if (_replAct != value)
                {
                    _replAct = value;
                    RaisePropertyChanged("ReplAct");
                }
            }
        }

        /// <summary>
        /// Идентификатор торговой сессии
        /// </summary>
        public int SessId
        {
            get { return _sessId; }
            set
            {
                if (_sessId != value)
                {
                    _sessId = value;
                    RaisePropertyChanged("SessId");
                }
            }
        }

        /// <summary>
        /// Уникальный числовой идентификатор инструмента
        /// </summary>
        public int IsinId
        {
            get { return _isinId; }
            set
            {
                if (_isinId != value)
                {
                    _isinId = value;
                    RaisePropertyChanged("IsinId");
                }
            }
        }

        /// <summary>
        /// Описатель инструмента
        /// </summary>
        public string ShortIsin
        {
            get { return _shortIsin; }
            set
            {
                if (_shortIsin != value)
                {
                    _shortIsin = value;
                    RaisePropertyChanged("ShortIsin");
                }
            }
        }

        /// <summary>
        /// Символьный код инструмента
        /// </summary>
        public string Isin
        {
            get { return _isin; }
            set
            {
                if (_isin != value)
                {
                    _isin = value;
                    RaisePropertyChanged("Isin");
                }
            }
        }

        /// <summary>
        /// Наименование инструмента
        /// </summary>
        public string Name
        {
            get { return _name; }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    RaisePropertyChanged("Name");
                }
            }
        }

        /// <summary>
        /// Смещение от спота
        /// </summary>
        public int InstTerm
        {
            get { return _instTerm; }
            set
            {
                if (_instTerm != value)
                {
                    _instTerm = value;
                    RaisePropertyChanged("InstTerm");
                }
            }
        }

        /// <summary>
        /// Код базового актива
        /// </summary>
        public string CodeVcb
        {
            get { return _codeVcb; }
            set
            {
                if (_codeVcb != value)
                {
                    _codeVcb = value;
                    RaisePropertyChanged("CodeVcb");
                }
            }
        }

        /// <summary>
        /// Признак наличия лимитов в торгах
        /// </summary>
        public int IsLimited
        {
            get { return _isLimited; }
            set
            {
                if (_isLimited != value)
                {
                    _isLimited = value;
                    RaisePropertyChanged("IsLimited");
                }
            }
        }

        /// <summary>
        /// Верхний лимит цены
        /// </summary>
        public Decimal LimitUp
        {
            get { return _limitUp; }
            set
            {
                if (_limitUp != value)
                {
                    _limitUp = value;
                    RaisePropertyChanged("LimitUp");
                }
            }
        }

        /// <summary>
        /// Нижний лимит цены
        /// </summary>
        public Decimal LimitDown
        {
            get { return _limitDown; }
            set
            {
                if (_limitDown != value)
                {
                    _limitDown = value;
                    RaisePropertyChanged("LimitDown");
                }
            }
        }

        /// <summary>
        /// Скорректированная расчетная цена предыдущей сессии
        /// </summary>
        public Decimal OldKotir
        {
            get { return _oldKotir; }
            set
            {
                if (_oldKotir != value)
                {
                    _oldKotir = value;
                    RaisePropertyChanged("OldKotir");
                }
            }
        }

        /// <summary>
        /// ГО покупателя
        /// </summary>
        public Decimal BuyDeposit
        {
            get { return _buyDeposit; }
            set
            {
                if (_buyDeposit != value)
                {
                    _buyDeposit = value;
                    RaisePropertyChanged("BuyDeposit");
                }
            }
        }

        /// <summary>
        /// ГО продавца
        /// </summary>
        public Decimal SellDeposit
        {
            get { return _sellDeposit; }
            set
            {
                if (_sellDeposit != value)
                {
                    _sellDeposit = value;
                    RaisePropertyChanged("SellDeposit");
                }
            }
        }

        /// <summary>
        /// Количество знаков после запятой в цене
        /// </summary>
        public int Roundto
        {
            get { return _roundto; }
            set
            {
                if (_roundto != value)
                {
                    _roundto = value;
                    RaisePropertyChanged("Roundto");
                }
            }
        }

        /// <summary>
        /// Минимальный шаг цены
        /// </summary>
        public Decimal MinStep
        {
            get { return _minStep; }
            set
            {
                if (_minStep != value)
                {
                    _minStep = value;
                    RaisePropertyChanged("MinStep");
                }
            }
        }

        /// <summary>
        /// К-во единиц базового актива в инструменте
        /// </summary>
        public int LotVolume
        {
            get { return _lotVolume; }
            set
            {
                if (_lotVolume != value)
                {
                    _lotVolume = value;
                    RaisePropertyChanged("LotVolume");
                }
            }
        }

        /// <summary>
        /// Стоимость шага цены
        /// </summary>
        public Decimal StepPrice
        {
            get { return _stepPrice; }
            set
            {
                if (_stepPrice != value)
                {
                    _stepPrice = value;
                    RaisePropertyChanged("StepPrice");
                }
            }
        }

        /// <summary>
        /// Дата окончания обращения инструмента
        /// </summary>
        public DateTime DPg
        {
            get { return _dPg; }
            set
            {
                if (_dPg != value)
                {
                    _dPg = value;
                    RaisePropertyChanged("DPg");
                }
            }
        }

        /// <summary>
        /// Признак вхождения фьючерса в межмесячный спрэд. 1 – входит; 0 – не входит
        /// </summary>
        public int IsSpread
        {
            get { return _isSpread; }
            set
            {
                if (_isSpread != value)
                {
                    _isSpread = value;
                    RaisePropertyChanged("IsSpread");
                }
            }
        }

        /// <summary>
        /// Коэффициент межмесячного спрэда
        /// </summary>
        public Decimal Coeff
        {
            get { return _coeff; }
            set
            {
                if (_coeff != value)
                {
                    _coeff = value;
                    RaisePropertyChanged("Coeff");
                }
            }
        }

        /// <summary>
        /// Дата исполнения инструмента
        /// </summary>
        public DateTime Dexp
        {
            get { return _dExp; }
            set
            {
                if (_dExp != value)
                {
                    _dExp = value;
                    RaisePropertyChanged("Dexp");
                }
            }
        }

        /// <summary>
        /// Признак того, что фьючерс торгуется в процентах. 1 - торгуется процентах, 0 – торгуется не в процентах
        /// </summary>
        public int IsPercent
        {
            get { return _isPercent; }
            set
            {
                if (_isPercent != value)
                {
                    _isPercent = value;
                    RaisePropertyChanged("IsPercent");
                }
            }
        }

        /// <summary>
        /// Процентная ставка для расчета вариационной маржи по процентным фьючерсам
        /// </summary>
        public Decimal PercentRate
        {
            get { return _percentRate; }
            set
            {
                if (_percentRate != value)
                {
                    _percentRate = value;
                    RaisePropertyChanged("PercentRate");
                }
            }
        }

        /// <summary>
        /// Котировка после последнего клиринга
        /// </summary>
        public Decimal LastClQuote
        {
            get { return _lastClQuote; }
            set
            {
                if (_lastClQuote != value)
                {
                    _lastClQuote = value;
                    RaisePropertyChanged("LastClQuote");
                }
            }
        }

        /// <summary>
        /// Поле признаков
        /// Поле signs является битовой и принимает следующие значения:
        /// 0x01 Признак торговли в вечернюю сессию
        /// 0x02 Маржируемый (1) или с уплатой премии (0)
        /// 0x04 Спот
        /// 0x08 Главный спот
        /// 0x10 Признак анонимной торговли
        /// 0x20 Признак неанонимной торговли
        /// 0x40 Признак торговли в основную сессию
        /// 0x100 Признак инструмента-связки
        /// 0x800 Признак инструмента RTS Money
        /// 0x1000 Признак основной цены для составных инструментов:
        ///• 0 - инструмент котируется в своп-цене
        ///• 1 - инструмент котируется в ставке
        ///Значение признака влияет на смысл поля цены для данного инструмента в потоках со стаканами.
        /// </summary>
        public int Signs
        {
            get { return _signs; }
            set
            {
                if (_signs != value)
                {
                    _signs = value;
                    RaisePropertyChanged("Signs");
                }
            }
        }

        /// <summary>
        /// Признак торговли в вечернюю сессию
        /// • Поле is_trade_evening является битовой маской:
        /// 0 Инструмент не торгуется
        /// 1 Инструмент торгуется в вечернюю сессию
        /// 2 Инструмент торгуется в дневную сессию
        /// </summary>
        public int IsTradeEvening
        {
            get { return _isTradeEvening; }
            set
            {
                if (_isTradeEvening != value)
                {
                    _isTradeEvening = value;
                    RaisePropertyChanged("IsTradeEvening");
                }
            }
        }

        /// <summary>
        /// Уникальный числовой код Главного Спота
        /// </summary>
        public int Ticker
        {
            get { return _ticker; }
            set
            {
                if (_ticker != value)
                {
                    _ticker = value;
                    RaisePropertyChanged("Ticker");
                }
            }
        }

        /// <summary>
        /// Состояние торговли по инструменту
        /// Поле state может принимать следующие значения:
        /// 0 Сессия по этому инструменту назначена. Нельзя ставить заявки, но можно удалять по этому инструменту.
        /// 1 Сессия по этому инструменту идет. Можно ставить и удалять заявки по этому инструменту.
        /// 2 Приостановка торгов по всем инструментам. Нельзя ставить заявки, но можно удалять.
        /// 3 Сессия по этому инструменту принудительно завершена. Нельзя ставить и удалять заявки по этому инструменту.
        /// 4 Сессия по этому инструменту завершена по времени. Нельзя ставить и удалять заявки по этому инструменту.
        /// 5 Приостановка торгов по этому инструменту. Нельзя ставить заявки, но можно удалять по этому инструменту.
        /// </summary>
        public int State
        {
            get { return _state; }
            set
            {
                if (_state != value)
                {
                    _state = value;
                    RaisePropertyChanged("State");
                }
            }
        }

        /// <summary>
        /// Направление цены инструмен
        /// • Поле price_dir может принимать следующие значения:
        /// 0 Стандартный порядок сортировки цен
        /// 1 Обратный порядок сортировки цен
        /// </summary>
        public int PriceDir
        {
            get { return _priceDir; }
            set
            {
                if (_priceDir != value)
                {
                    _priceDir = value;
                    RaisePropertyChanged("PriceDir");
                }
            }
        }

        /// <summary>
        /// Тип связки
        /// • Поле multileg_type может принимать следующие значения:
        /// 0 Обычный инструмент - не связка
        /// 1 Связка, торгуемая в режиме Репо
        /// Наличие данного признака означает, что инструмент может торговаться как в режиме Репо, так и в режиме связанных заявок.
        /// 2 Валютный своп
        /// 3 Календарный спред
        /// </summary>
        public int MultilegType
        {
            get { return _multilegType; }
            set
            {
                if (_multilegType != value)
                {
                    _multilegType = value;
                    RaisePropertyChanged("MultilegType");
                }
            }
        }

        /// <summary>
        /// Количество инструментов в связке
        /// </summary>
        public int LegsQty
        {
            get { return _legsQty; }
            set
            {
                if (_legsQty != value)
                {
                    _legsQty = value;
                    RaisePropertyChanged("LegsQty");
                }
            }
        }

        /// <summary>
        /// Cтоимость шага цены вечернего клиринга
        /// </summary>
        public Decimal StepPriceClr
        {
            get { return _stepPriceClr; }
            set
            {
                if (_stepPriceClr != value)
                {
                    _stepPriceClr = value;
                    RaisePropertyChanged("StepPriceClr");
                }
            }
        }

        /// <summary>
        /// Cтоимость шага цены пром. клиринга
        /// </summary>
        public Decimal StepPriceInterclr
        {
            get { return _stepPriceInterclr; }
            set
            {
                if (_stepPriceInterclr != value)
                {
                    _stepPriceInterclr = value;
                    RaisePropertyChanged("StepPriceInterclr");
                }
            }
        }

        /// <summary>
        /// Стоимость минимального шага цены, выраженная в валюте
        /// </summary>
        public Decimal StepPriceCurr
        {
            get { return _stepPriceCurr; }
            set
            {
                if (_stepPriceCurr != value)
                {
                    _stepPriceCurr = value;
                    RaisePropertyChanged("StepPriceCurr");
                }
            }
        }

        /// <summary>
        /// Дата ввода инструмента в обращение
        /// </summary>
        public DateTime DStart
        {
            get { return _dStart; }
            set
            {
                if (_dStart != value)
                {
                    _dStart = value;
                    RaisePropertyChanged("DStart");
                }
            }
        }

        /// <summary>
        /// Биржевой сбор
        /// </summary>
        public Decimal ExchPay
        {
            get { return _exchPay; }
            set
            {
                if (_exchPay != value)
                {
                    _exchPay = value;
                    RaisePropertyChanged("ExchPay");
                }
            }
        }

        #endregion


        #region event PropertyChangedEventHandler

        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        #region processing
        public static FutSessContents ParseFutSessContents(Dictionary<String, String> relation)
        {
            FutSessContents tmp = new FutSessContents();
            tmp.Parse(relation);
            return tmp;
        }

        public void Parse(Dictionary<String, String> relation)
        {
            foreach (String field in relation.Keys)
            {
                String value = relation[field];

                switch (field)
                {
                    case "replID": long.TryParse(value, out _replId); break;
                    case "replRev": long.TryParse(value, out _replRev); break;
                    case "replAct": long.TryParse(value, out _replAct); break;
                    case "sess_id": int.TryParse(value, out _sessId); break;
                    case "isin_id": int.TryParse(value, out _isinId); break;
                    case "short_isin": _shortIsin = value; break;
                    case "isin": _isin = value; break;
                    case "name": _name = value; break;
                    case "inst_term": int.TryParse(value, out _instTerm); break;
                    case "code_vcb": _codeVcb = value; break;
                    case "is_limited": int.TryParse(value, out _isLimited); break;
                    case "limit_up": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _limitUp); break;
                    case "limit_down": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _limitDown); break;
                    case "old_kotir": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _oldKotir); break;
                    case "buy_deposit": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _buyDeposit); break;
                    case "sell_deposit": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _sellDeposit); break;
                    case "roundto": int.TryParse(value, out _roundto); break;
                    case "min_step": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _minStep); break;
                    case "lot_volume": int.TryParse(value, out _lotVolume); break;
                    case "step_price": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _stepPrice); break;
                    case "d_pg": DateTime.TryParse(value, out _dPg); break;
                    case "is_spread": int.TryParse(value, out _isSpread); break;
                    case "coeff": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _coeff); break;
                    case "d_exp": DateTime.TryParse(value, out _dExp); break;
                    case "is_percent": int.TryParse(value, out _isPercent); break;
                    case "percent_rate": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _percentRate); break;
                    case "last_cl_quote": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _lastClQuote); break;
                    case "signs": int.TryParse(value, out _signs); break;
                    case "is_trade_evening": int.TryParse(value, out _isTradeEvening); break;
                    case "ticker": int.TryParse(value, out _ticker); break;
                    case "state": int.TryParse(value, out _state); break;
                    case "price_dir": int.TryParse(value, out _priceDir); break;
                    case "multileg_type": int.TryParse(value, out _multilegType); break;
                    case "legs_qty": int.TryParse(value, out _legsQty); break;
                    case "step_price_clr": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _stepPriceClr); break;
                    case "step_price_interclr": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _stepPriceInterclr); break;
                    case "step_price_curr": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _stepPriceCurr); break;
                    case "d_start": DateTime.TryParse(value, out _dStart); break;
                    case "exch_pay": Decimal.TryParse(value, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out _exchPay); break; 


                };
            }
        }

        public static void AddValueToObsColFutSessContents(FutSessContents tmp)
        {
            MainWindow.StaticLevel._dataProvider.FutSessContentsList.Add(tmp);
        }

        #endregion
    }
}
